package br.org.reconcavotecnologia.update19.registro;

import java.io.File;
import java.util.Set;

import br.org.reconcavotecnologia.update19.registro.engine.Acao;
import br.org.reconcavotecnologia.update19.registro.engine.MaquinaAcao;
import br.org.reconcavotecnologia.update19.registro.util.UtilPropriedades;

/**
 * Classe com recursos de comparação entre arquivos properties. É utilizada para
 * definir a lista de ações para atualização do sistema.
 * 
 * @author Cássio Oliveira
 * 
 * TODO Utilizar arquivos temporários para fazer a comparação ao invés dos arquivos originais
 * 
 */
public class MaquinaUpdate {

	/** Arquivo de propriedades local */
	private UtilPropriedades propCliente;

	/** Arquivo de propriedades remoto */
	private UtilPropriedades propServidor;
	
	/** Máquina de ações. responsável por execurtar as ações de cominicação com o propServidor e manipulação de arquivos */
	private MaquinaAcao maquinaAcao;
	
	/** Método construtor define o arquivo fonte e o arquivo do propServidor */
	public MaquinaUpdate(String client, String instalacaoServidor, String server) {
		this.propCliente = new UtilPropriedades(new File(client));
		this.propServidor = new UtilPropriedades(new File(server));
		this.maquinaAcao = new MaquinaAcao(instalacaoServidor);
	}
	
	/** Faz download do arquivo de informações do servidor */
	public void downloadInfoServidor(){
		maquinaAcao.download(propServidor.getName(), "server.info");
	}

	/** Inicia o processo de comparação */
	public void analizar(){

		// resgata a lista de hash do arquivo propCliente e do propServidor
		Set<String> arquivosServidor = this.propServidor.getListaArquivos();
		Set<String> arquivosCliente = this.propCliente.getListaArquivos();

		/*
		 * ARQUIVOS A SEREM ATUALIZADOS OU SIMPLESMENTE BAIXADOS
		 */

		// Ação a ser configurada
		Acao acao = null;
		
		// verifica lista de arquivos
		for (String arquivoS : arquivosServidor) {

			System.out.print("MaquinaUpdate.start() > " + arquivoS + " > ");

 			// caso o arquivo idicado no propServidor exista localmente
			if(arquivosCliente.contains(arquivoS)){
				
				// verifica se a chave é a mesma
				if(this.propServidor.readHash(arquivoS).equals(this.propCliente.readHash(arquivoS))){
					
					// caso as chaves sejam iguais, não há ação a ser realizada. O arquivo está atualizado!
					System.out.println("ARQUIVO JÁ ATUALIZADO");
				
				}else{
					
					// chaves diferentes. este arquivo deve ser baixado e o arquivo antigo deve ser substituído.
					// TODO Cadastrar uma ação de DOWNLOAD COM SUBSTITUIÇÃO (ATUALIZA)
					System.out.println("DOWNLOAD COM SUBSTITUIÇÃO");

					// instancia uma nova ação
					acao = new Acao();
					// define seu tipo
					acao.setTipoAcao(MaquinaAcao.ATUALIZA);
					// define sua lista de parametros
					acao.addParametro(arquivoS);
					acao.addParametro(arquivoS);
				}
				
			}else{
				
				// caso não encontre a chave, significa que o arquivo atual não existe. Este arquivo deve ser baixado.
				// TODO Cadastrar uma ação de DOWNLOAD DE ARQUIVO
				System.out.println("DOWNLOAD DE ARQUIVO");
				
				acao = new Acao();
				acao.setTipoAcao(MaquinaAcao.DOWNLOAD);
				acao.addParametro(arquivoS);
				
			}
			
			// se alguma ação foi configurada, adiciona na lista
			if(acao != null){
				// adiciona a ação configurada para a lista de ações
				maquinaAcao.addAcao(acao);
			}
		}

		/*
		 * ARQUIVOS A SEREM DELETADOS
		 */

		// Verifica se existem arquivos obsoletos
		for (String arquivoC : arquivosCliente) {
			if(!arquivosServidor.contains(arquivoC)){
				System.out.print("MaquinaUpdate.start() > " + arquivoC + " > ");
				// Caso o propServidor não possua o arquivo indicado, ele está obsoleto.
				System.out.println("REMOVER ARQUIVO");
				acao = new Acao();
				acao.setTipoAcao(MaquinaAcao.REMOVER);
				acao.addParametro(arquivoC);
				maquinaAcao.addAcao(acao);
			}
		}
	}
	
	/** Processa as ações cadastrada na lista de ações */
	public void executarAcoes(){
		this.maquinaAcao.executarAcoes();
	}

}
